package com.java.concurrency.stampedlocktest;


import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.locks.StampedLock;

public class StampedLockVo1 {
    private double x,y;
    private final StampedLock s1=new StampedLock();

    void move(double x,double y){ //多个线程调用该函数，修改x和y的值
        long stamp = s1.writeLock();
        try{
            this.x=x;
            this.y=y;
        }catch (Exception e){

        }finally {
            s1.unlockWrite(stamp);
        }
    }

    double distanceFromOrigin(){ //多个线程调用该函数求距离
        long stamp = s1.tryOptimisticRead();  //使用乐观读
        double currentX=x; double currentY=y; //将共享变量拷贝到线程栈
        if(!s1.validate(stamp)){    //拷贝期间有其他线程修改该数据，读的是脏数据
            stamp =s1.readLock(); 	//升级为悲观读
            try{
                currentX=x;
                currentY=y;
            }catch (Exception e){

            }finally {
                s1.unlockRead(stamp);
            }
        }

        return  Math.sqrt(currentX*currentX+currentY*currentY);
    }


    public static void main(String[] args) {
        StampedLockVo1 stampedLockVo1 = new StampedLockVo1();

        for(int i=0;i<100;i++){
            new Thread(()->{stampedLockVo1.move(ThreadLocalRandom.current().nextInt(10),ThreadLocalRandom.current().nextInt(10));}).start();
            new Thread(()->{
                System.out.println(stampedLockVo1.distanceFromOrigin());
            }).start();
        }

    }
}
